SWEP.Author = "Brwarner";
SWEP.Contact = "";
SWEP.Purpose = "Allows building of walls and other structures";
SWEP.Instructions = "Left click construct peice, right click rotates and reload opens menu.";

SWEP.Spawnable = true;
SWEP.AdminSpawnable = true;

SWEP.ViewModel = "models/weapons/v_physcannon.mdl";
SWEP.WorldModel = "models/weapons/w_physics.mdl";

SWEP.Primary.ClipSize = -1;
SWEP.Primary.DefaultClip = -1;
SWEP.Primary.Automatic = false;
SWEP.Primary.Ammo = "none";

SWEP.Secondary.ClipSize = -1;
SWEP.Secondary.DefaultClip = -1;
SWEP.Secondary.Automatic = false;
SWEP.Secondary.Ammo = "none";

//Load up blocks just to find out their models
include('entities/bh_block/block.lua');
print(SWEP.Folder);

local blockTypes = file.FindInLua( "entities/bh_block/blocks/*.lua");

//Start reading a block table
if(SERVER) then SWEP.Blocks =  {}; 
else Blocks = {};
end


//For each block
i = 0;
for key, val in pairs( blockTypes ) do
	local char1,char2,blocktype = string.find(val, "([%w_]*)\.lua");
	
	BLOCK = BHBlock:Create();
	BLOCK.File = blocktype;
	AddCSLuaFile("entities/bh_block/blocks/"..val);
	include("entities/bh_block/blocks/"..val);
	
	//Read into a table
	print("SWEP loaded " .. val);
	if(BLOCK.PlayerSpawn) then
		if(SERVER) then SWEP.Blocks[i] = BLOCK;
		else Blocks[i] = BLOCK;
		end
		i = i + 1;
	end
	BLOCK = nil;
end

function SWEP:Deploy()
	//Setup inital variables
	self.yaw = 0;
	self.curBlock = -1;
	
	//Create ghost entity
	self.ghost = ents.Create("prop_physics");
	return true;
end 

//Called to change the model of the entity
function SWEP:ChangeGhostModel(model)
	self.ghost:SetModel(model);
	self.ghost:Spawn();
	
	self.ghost:PhysicsInit( SOLID_VPHYSICS );
	self.ghost:SetMoveType(MOVETYPE_NONE);
	self.ghost:SetSolid(SOLID_NONE);
	self.ghost:SetColor(255, 255, 255, 100);
end

function SWEP:OwnerChanged()
	if(self.ghost && SERVER && self.ghost:IsValid()) then
		self.ghost:Remove();
	end
	return true;
end

function SWEP:Think()
	if(!SERVER) then return end;
	
	if(self.builder) then
		if(self.builder:IsValid()) then
			self:SetNetworkedInt("isBuilding", 1);
			self:SetNetworkedFloat("buildPercent", self.builder:GetPercent());
		else
			self:SetNetworkedInt("isBuilding", 0);
		end
	else
		self:SetNetworkedInt("isBuilding", 0);
	end
	
	local ty = self.Owner:GetInfoNum("buildgun_blocktype");
	if(ty != self.curBlock) then
		self.curBlock = ty;
		self:ChangeGhostModel(self.Blocks[ty].Model);
	end
	local tr = self.Owner:GetEyeTrace();
	
	if(!tr.Hit) then return end;
	
	if(self.ghost && self.ghost:IsValid()) then
		local pos = tr.HitPos - tr.HitNormal * self.ghost:OBBMins().z;
		self.ghost:SetPos(pos);
		local Ang = tr.HitNormal:Angle();
		Ang.p = Ang.p + 90;
		Ang.y = Ang.y + self.yaw;
		self.ghost:SetAngles(Ang);
		if(self:ValidateSpot(pos, tr.StartPos, false)) then
			self.ghost:SetColor(255, 255, 255, 100);
		else
			self.ghost:SetColor(255, 0, 0, 100);
		end
	end
	
end

function SWEP:NotifyError(text)
	local ply = self.Weapon.Owner;
	hook.Call("ShowNotice", nil, text, ply);
end

function SWEP:ValidateSpot(pos, start, err)
	if(!self.Blocks[self.curBlock]:ValidPos(pos, err, self.Weapon.Owner)) then 
		return false; 
	end
	local v = pos - start;
	if(v:Length() > 300) then 
		if(err) then 
			self:NotifyError("Distance is to great!");
		end
		return false; 
	end
	return true;
end

function SWEP:Holster()
	if(self.ghost && SERVER && self.ghost:IsValid()) then
		self.ghost:Remove();
	end
	return true;
end

function SWEP:OnDrop()
	if(self.ghost && self.ghost:IsValid()) then
		self.ghost:Remove();
	end
	return true;
end

function SWEP:OnRemove()
	if(self.ghost && self.ghost:IsValid()) then
		self.ghost:Remove();
	end
	return true;
end

function SetEntPos(tr, ent)
	ent:SetPos(tr.HitPos - tr.HitNormal * ent:OBBMins().z);
end

function SWEP:PrimaryAttack()
	if(!SERVER) then return end
	
	if(self.builder) then
		if(self.builder:IsValid()) then 
			self:NotifyError("Can only build 1 block at a time!");
			return; 
		end
	end
	local tr = self.Owner:GetEyeTrace();
	if(tr.Entity:IsPlayer()) then return; end
	if(tr.Entity:GetClass() == "prop_physics" || tr.Entity:GetClass() == "prop_dynamic") then return; end
	if(!self:ValidateSpot(tr.HitPos, tr.StartPos, true)) then return; end
	if(tr.Entity:GetClass() == "func_divider") then 
		self:NotifyError("Cannot place blocks on Divider!");
		return; 
	end
	if(!hook.Call("CheckLimit", nil, self.Weapon.Owner:Team())) then
		self:NotifyError("Reached Block Limit!");
		return;
	end
	hook.Call("IncrementBlocks", nil, self.Weapon.Owner:Team(), 1);
	
	self.builder = ents.Create("bh_builder");
	self.builder:SetPos(tr.HitPos);
	self.builder.userid = self.Weapon.Owner:EntIndex();
	self.builder:Spawn();
	
	SetEntPos(tr, self.builder);
	local Ang = tr.HitNormal:Angle();
	Ang.p = Ang.p +  90;
	Ang.y = Ang.y + self.yaw;
	self.builder:SetAngles(Ang);
	local bt = self.Blocks[self.curBlock].BuildTime;
	if(hook.Call("GetPhaseNumber") == 1) then bt = bt * 3; end
	self.builder:StartBuild(self.Blocks[self.curBlock].File, bt, self.Owner:Team(), tr);
	constraint.Weld(self.builder, tr.Entity, tr.PhysicsBone, 0, 0);
	
	return true;
end 

function SWEP:SecondaryAttack()
	if(!SERVER) then return end;
	
	self.yaw = self.yaw + 45;
	if(self.yaw >= 360) then self.yaw = 0; end;
end 

function SWEP:Reload()
	if(!SERVER) then return end;
	
	local ply = self.Weapon:GetOwner();
	ply:ConCommand("weapon_buildgun_show_cpanel");
end